package ar.edu.unicen.exa.isistan.archassis.view.classes.classitem;

import java.util.ArrayList;
import java.util.List;

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.wb.swt.SWTResourceManager;

import swing2swt.layout.BorderLayout;
import ar.edu.unicen.exa.isistan.archassis.ia.api.db.JavaClass;
import ar.edu.unicen.exa.isistan.archassis.ia.seed.ImplementsSeed;
import ar.edu.unicen.exa.isistan.archassis.ia.seed.MetodoSeed;
import ar.edu.unicen.exa.isistan.archassis.ia.seed.Run;
import ar.edu.unicen.exa.isistan.archassis.ia.seed.VariableSeed;
import ar.edu.unicen.exa.isistan.archassis.view.classes.classitem.classdata.ClassDataComposite;
import ar.edu.unicen.exa.isistan.archassis.view.classes.classitem.classdata.ClassRunComposite;
import ar.edu.unicen.exa.isistan.archassis.view.classes.classitem.classdata.ClassVariableComposite;

public class ClassComposite extends Composite {
//	private Label classNameLabel;
	private Composite classDataPanel;

	/**
	 * Create the composite.
	 * @param parent
	 * @param style
	 */
	public ClassComposite(Composite parent, int style) {
		super(parent, SWT.BORDER);
		setBackground(SWTResourceManager.getColor(SWT.COLOR_WHITE));
		setLayout(new BorderLayout(0, 0));
		
//		classNameLabel = new Label(this, SWT.NONE);
//		classNameLabel.setBackground(SWTResourceManager.getColor(SWT.COLOR_WHITE));
//		classNameLabel.setLayoutData(BorderLayout.NORTH);
//		classNameLabel.setText("Nombre de la clase");
		
		classDataPanel = new Composite(this, SWT.NONE);
		classDataPanel.setBackground(SWTResourceManager.getColor(SWT.COLOR_WHITE));
		classDataPanel.setLayoutData(BorderLayout.CENTER);
		classDataPanel.setLayout(new FillLayout(SWT.VERTICAL));
		
		Composite composite = new Composite(this, SWT.NONE);
		composite.setLayoutData(BorderLayout.NORTH);
		composite.setLayout(new BorderLayout(0, 0));
		
		classNameCheck = new Button(composite, SWT.CHECK);
		classNameCheck.setLayoutData(BorderLayout.CENTER);
		classNameCheck.setText("Nombre de la clase");
		classNameCheck.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				disableChildrens(classNameCheck.getSelection());
			}
		});
		
		Label lblNewLabel = new Label(composite, SWT.NONE);
		lblNewLabel.setImage(SWTResourceManager.getImage(ClassComposite.class, "/veltemp/img/Class.png"));
		lblNewLabel.setLayoutData(BorderLayout.WEST);
	}
	
	private void disableChildrens(boolean value) {
		compositeExtend.setEnabled(value);
		for (ClassDataComposite classDataComposite : compositesImplements) {
			classDataComposite.setEnabled(value);
		}
		for (ClassVariableComposite classVariableComposite : compositesVariable) {
			classVariableComposite.setEnabled(value);
		}
		for (ClassDataComposite classMetodoComposite : compositesMetodo) {
			classMetodoComposite.setEnabled(value);
		}
	}
	@Override
	protected void checkSubclass() {
		// Disable the check that prevents subclassing of SWT components
	}

	private ClassDataComposite compositeExtend = null;
	private List<ClassDataComposite> compositesImplements = new ArrayList<ClassDataComposite>();
	private List<ClassVariableComposite> compositesVariable = new ArrayList<ClassVariableComposite>();
	private List<ClassRunComposite> compositesMetodo = new ArrayList<ClassRunComposite>();
	private JavaClass javaClass;
	private Button classNameCheck;
	
	
	public JavaClass getJavaClass() {
		String name = javaClass.getNombre();
		String ruExtends = JavaClass.DEFAULT_EXTENDS;
		if (compositeExtend.isChecked()) {
			ruExtends = compositeExtend.getValue();
		}
		List<String> rnImplements = new ArrayList<String>();
		for (ClassDataComposite classDataComposite: compositesImplements) {
			if (classDataComposite.isChecked()) {
				rnImplements.add(classDataComposite.getValue());
			}
		}
		
		JavaClass result = new JavaClass(name, ruExtends, rnImplements);
		
		List<VariableSeed> variables = new ArrayList<VariableSeed>();
		for (ClassVariableComposite classVariableComposite: compositesVariable) {
			if (classVariableComposite.isChecked()) {
				variables.add(classVariableComposite.getVariable());
			}
		}
		result.setVariables(variables);
		
		List<MetodoSeed> metodos = new ArrayList<MetodoSeed>();
		for (ClassRunComposite classRunComposite: compositesMetodo) {
			if (classRunComposite.isChecked()) {
				int pos = metodos.indexOf(classRunComposite.getMetodo());
				if(pos != -1){
					metodos.get(pos).addEjecuta(classRunComposite.getReferencia());
				}else{
					MetodoSeed copia = new MetodoSeed(classRunComposite.getMetodo());
					copia.addEjecuta(classRunComposite.getReferencia());
					metodos.add(copia);
				}
			}
		}
		result.setMetodos(metodos);
		return result;
	}
	
	public void setJavaClass(JavaClass javaClass) {
		this.javaClass = javaClass;
		this.getClassNameCheck().setText(javaClass.getNombre());
	
		compositeExtend = createClassDataComposite(JavaClass.RU_EXTENDS, javaClass.getEntiende());
		
		for (ImplementsSeed c : javaClass.getImplementa()) {
			compositesImplements.add(createClassDataComposite(JavaClass.RN_IMPLEMENTS, c.getValor()));
		}
		for (VariableSeed javaVariable : javaClass.getVariables()) {
			compositesVariable.add(createClassVariableComposite(javaVariable));
		}
		for (MetodoSeed method : javaClass.getMetodos()) {
			for(Run rejecuta: method.getEjecuta()){
				compositesMetodo.add(createClassMetodoComposite(rejecuta ,method));
			}
		}
	}
	private ClassDataComposite createClassDataComposite(String relacion, String className) {
		ClassDataComposite javaExtends = new ClassDataComposite(getClassDataPanel());
		javaExtends.setValue(relacion,  className);
		return javaExtends;
	}
	private ClassVariableComposite createClassVariableComposite(VariableSeed javaVariable) {
		ClassVariableComposite javaExtends = new ClassVariableComposite(getClassDataPanel());
		javaExtends.setValue(javaVariable);
		return javaExtends;
	}
	private ClassRunComposite createClassMetodoComposite(Run ejecute, MetodoSeed metodo) {
		ClassRunComposite javaMet = new ClassRunComposite(getClassDataPanel());
		javaMet.setReferencia(ejecute, metodo);
		return javaMet;
	}
	


	protected Composite getClassDataPanel() {
		return classDataPanel;
	}

	public boolean isChecked() {
		return getClassNameCheck().getSelection();
	}
//	protected Button getClassNameCheck() {
//		return classNameCheck;
//	}
	protected Button getClassNameCheck() {
		return classNameCheck;
	}
}
